package com.joker.demo.admin.util;


import cn.hutool.core.date.DateUtil;
import com.joker.demo.admin.domain.po.JobInfoPO;
import com.joker.demo.admin.domain.po.JobLogPO;
import com.joker.demo.core.domain.enums.JobRunStatusEnum;
import com.joker.demo.core.domain.enums.JobSchedulingTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.support.CronExpression;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author : feixiang.li
 * @since : 2025-07-29 17:02
 */
@Slf4j
public class JobConvertUtils {

    private JobConvertUtils() {
    }


    /**
     * 将任务执行的时间、任务执行结果等信息转换成任务日志
     *
     * @param jobInfo 任务信息
     * @return 任务日志
     */
    public static JobLogPO convertJobLogWithNoParam(JobInfoPO jobInfo, String address) {
        JobLogPO jobLog = new JobLogPO();
        if (Objects.isNull(jobInfo)) {
            return jobLog;
        }
        jobLog.setJobId(jobInfo.getId());
        jobLog.setTriggerTime(jobInfo.getNextTriggerTime());
        jobLog.setTriggerCode(JobRunStatusEnum.INIT.getCode());

        // 设置执行器运行的地址
        jobLog.setExecutorAddress(address);
        jobLog.setExecutorHandler(jobInfo.getJobName());
        // 执行参数为空
        jobLog.setExecutorShardingParam(null);
        jobLog.setExecutorShardingIndex(0);
        jobLog.setExecutorFailRetryCount(0);
        return jobLog;
    }


    /**
     * 构建任务日志
     *
     * @param jobInfoList 任务日志列表
     * @return 任务日志列表
     */
    public static List<JobLogPO> convertJobLogWithParam(List<JobInfoPO> jobInfoList) {
        List<JobLogPO> jobLogList = new ArrayList<>();
        for (JobInfoPO jobInfo : jobInfoList) {
            JobLogPO jobLog = convertJobLogWithNoParam(jobInfo, null);
            jobLogList.add(jobLog);
        }
        return jobLogList;
    }


    public static void updateNextTriggerTime(JobInfoPO jobInfo) {
        if (jobInfo == null) {
            return;
        }

        JobSchedulingTypeEnum byCode = JobSchedulingTypeEnum.getByCode(jobInfo.getScheduleType());
        if (byCode == null) {
            return;
        }
        switch (byCode) {
            case CRON:
                Date nowDate = new Date();
                // cron表达式
                CronExpression cronExpression = CronExpression.parse(jobInfo.getCronExpression());
                Date now = Objects.isNull(jobInfo.getNextTriggerTime()) ? nowDate : jobInfo.getNextTriggerTime();
                if (now.before(nowDate)) {
                    now = nowDate;
                }
                ZonedDateTime nowZonedDateTime = now.toInstant().atZone(ZoneId.systemDefault());
                ZonedDateTime nextTriggerTime = cronExpression.next(nowZonedDateTime);
                // 转换为Instant然后转为Date
                if (Objects.isNull(nextTriggerTime)) {
                    return;
                }
                Date date = Date.from(nextTriggerTime.toInstant());
                jobInfo.setLastTriggerTime(jobInfo.getNextTriggerTime());
                jobInfo.setNextTriggerTime(date);
                log.error("现在时间:{}, cron 表达式:{},更新任务下次执行时间：{}", DateUtil.format(now, "yyyy-MM-dd HH:mm:ss"), jobInfo.getCronExpression(), DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
                break;
            case FIX_RATE:
                // TODO: 待办
                break;
            case MANUAL:
                jobInfo.setNextTriggerTime(null);
                break;
            default:
                break;
        }
    }
}
